home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
367_01
/
futi14as.zoo
/
getdate.y
< prev
next >
Wrap
Text File
|
1992-02-22
|
15KB
|
661 lines
%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO DST
%{
/* Originally from: Steven M. Bellovin (unc!smb) */
/* Dept. of Computer Science */
/* University of North Carolina at Chapel Hill */
/* @(#)getdate.y 2.17 11/30/87 */
/* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
This port is also distributed under the terms of the
GNU General Public License as published by the
Free Software Foundation.
Please note that this file is not identical to the
original GNU release, you should have received this
code as patch to the official release. */
#ifdef MSDOS
static char RCS_Id[] =
"$Header: e:/gnu/fileutil/RCS/getdate.y 1.4.0.2 90/09/19 12:27:47 tho Exp $";
#endif /* MSDOS */
/* #include "defs.h" JF not used any more */
#include <sys/types.h>
#ifdef USG
struct timeb
{
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};
static void ftime ();
#else
#include <sys/timeb.h>
#endif
#include <ctype.h>
#if defined(BSD4_2) || defined (BSD4_1C)
#include <sys/time.h>
#else /* sane */
#include <time.h>
#endif /* sane */
#if defined (STDC_HEADERS) || defined (USG)
#include <string.h>
#endif
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef sparc
#include <alloca.h>
#endif
#endif
#ifdef MSDOS
#include <malloc.h>
int getdate_yyparse (void);
long getdate (char *p, struct timeb *now);
void ftime (struct timeb *timeb);
static long dateconv (int mm, int dd, int yy, int h, int m, int s, int mer,
int zone, int dayflag);
static long dayconv (int ord, int day, long now);
static long timeconv (int hh, int mm, int ss, int mer);
static long monthadd (long sdate, long relmonth);
static long daylcorr (long future, long now);
static int lookup (char *id);
static int yyerror (char *s);
static int yylex (void);
#endif /* MSDOS */
#ifndef NULL
#define NULL 0
#endif
#define daysec (24L*60L*60L)
static int timeflag, zoneflag, dateflag, dayflag, relflag;
static time_t relsec, relmonth;
static int hh, mm, ss, merid, day_light;
static int dayord, dayreq;
static int month, day, year;
static int ourzone;
#define AM 1
#define PM 2
#define DAYLIGHT 1
#define STANDARD 2
#define MAYBE 3
static time_t timeconv();
static time_t daylcorr();
static lookup();
static int yylex ();
#define yyparse getdate_yyparse
static int yyerror ();
%}
%%
timedate: /* empty */
| timedate item
;
item: tspec
{timeflag++;}
| zone
{zoneflag++;}
| dtspec
{dateflag++;}
| dyspec
{dayflag++;}
| rspec
{relflag++;}
| nspec;
nspec: NUMBER
{if (timeflag && dateflag && !relflag) year = $1;
else if ($1 > 10000) {
dateflag++;
day= $1%100;
month= ($1/100)%100;
year = month/10000;
} else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
tspec: NUMBER MERIDIAN
{hh = $1; mm = 0; ss = 0; merid = $2;}
| NUMBER ':' NUMBER
{hh = $1; mm = $3; merid = 24;}
| NUMBER ':' NUMBER MERIDIAN
{hh = $1; mm = $3; merid = $4;}
| NUMBER ':' NUMBER NUMBER
{hh = $1; mm = $3; merid = 24;
day_light = STANDARD; ourzone = -($4%100 + 60*($4/100));}
| NUMBER ':' NUMBER ':' NUMBER
{hh = $1; mm = $3; ss = $5; merid = 24;}
| NUMBER ':' NUMBER ':' NUMBER MERIDIAN
{hh = $1; mm = $3; ss = $5; merid = $6;}
| NUMBER ':' NUMBER ':' NUMBER NUMBER
{hh = $1; mm = $3; ss = $5; merid = 24;
day_light = STANDARD; ourzone = -($6%100 + 60*($6/100));};
zone: ZONE dst
{ourzone = $1; day_light = $2;}
| DAYZONE
{ourzone = $1; day_light = DAYLIGHT;};
dst: /* empty */
{ $$ = STANDARD; }
| DST
{ $$ = DAYLIGHT; };
dyspec: DAY
{dayord = 1; dayreq = $1;}
| DAY ','
{dayord = 1; dayreq = $1;}
| NUMBER DAY
{dayord = $1; dayreq = $2;};
dtspec: NUMBER '/' NUMBER
{month = $1; day = $3;}
| NUMBER '/' NUMBER '/' NUMBER
{month = $1; day = $3; year = $5;}
| MONTH NUMBER
{month = $1; day = $2;}
| MONTH NUMBER ',' NUMBER
{month = $1; day = $2; year = $4;}
| NUMBER MONTH
{month = $2; day = $1;}
| NUMBER MONTH NUMBER
{month = $2; day = $1; year = $3;};
rspec: NUMBER UNIT
{relsec += 60L * $1 * $2;}
| NUMBER MUNIT
{relmonth += $1 * $2;}
| NUMBER SUNIT
{relsec += $1;}
| UNIT
{relsec += 60L * $1;}
| MUNIT
{relmonth += $1;}
| SUNIT
{relsec++;}
| rspec AGO
{relsec = -relsec; relmonth = -relmonth;};
%%
static int mdays[12] =
{31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define epoch 1970
extern struct tm *localtime();
static time_t
dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
int mm, dd, yy, h, m, s, mer, zone, dayflag;
{
time_t tod, jdate;
register int i;
if (yy < 0) yy = -yy;
if (yy < 100) yy += 1900;
mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
dd < 1 || dd > mdays[--mm]) return (-1);
jdate = dd-1;
for (i=0; i<mm; i++) jdate += mdays[i];
for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
jdate *= daysec;
jdate += zone * 60L;
if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
jdate += tod;
if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
jdate += -1*60*60;
return (jdate);
}
static time_t
dayconv(ord, day, now)
int ord, day; time_t now;
{
register struct tm *loctime;
time_t tod;
tod = now;
loctime = localtime(&tod);
tod += daysec * ((day - loctime->tm_wday + 7) % 7);
tod += 7*daysec*(ord<=0?ord:ord-1);
return daylcorr(tod, now);
}
static time_t
timeconv(hh, mm, ss, mer)
register int hh, mm, ss, mer;
{
if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
switch (mer) {
case AM: if (hh < 1 || hh > 12) return(-1);
return (60L * ((hh%12)*60L + mm)+ss);
case PM: if (hh < 1 || hh > 12) return(-1);
return (60L * ((hh%12 +12)*60L + mm)+ss);
case 24: if (hh < 0 || hh > 23) return (-1);
return (60L * (hh*60L + mm)+ss);
default: return (-1);
}
}
static time_t
monthadd(sdate, relmonth)
time_t sdate, relmonth;
{
struct tm *ltime;
time_t dateconv();
int mm, yy;
if (relmonth == 0) return 0;
ltime = localtime(&sdate);
mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
yy = mm/12;
mm = mm%12 + 1;
return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
}
static time_t
daylcorr(future, now)
time_t future, now;
{
int fdayl, nowdayl;
nowdayl = (localtime(&now)->tm_hour+1) % 24;
fdayl = (localtime(&future)->tm_hour+1) % 24;
return (future-now) + 60L*60L*(nowdayl-fdayl);
}
static char *lptr;
static int
yylex()
{
extern int yylval;
int sign;
register char c;
register char *p;
char idbuf[20];
int pcnt;
for (;;) {
while (isspace(*lptr))
lptr++;
if (isdigit(c = *lptr) || c == '-' || c == '+') {
if (c== '-' || c == '+') {
if (c=='-') sign = -1;
else sign = 1;
if (!isdigit(*++lptr)) {
/* yylval = sign; return (NUMBER); */
return yylex(); /* skip the '-' sign */
}
} else sign = 1;
yylval = 0;
while (isdigit(c = *lptr++))
yylval = 10*yylval + c - '0';
yylval *= sign;
lptr--;
return (NUMBER);
} else if (isalpha(c)) {
p = idbuf;
while (isalpha(c = *lptr++) || c=='.')
if (p < &idbuf[sizeof(idbuf)-1]) *p++ = c;
*p = '\0';
lptr--;
return (lookup(idbuf));
}
else if (c == '(') {
pcnt = 0;
do {
c = *lptr++;
if (c == '\0') return(c);
else if (c == '(') pcnt++;
else if (c == ')') pcnt--;
} while (pcnt > 0);
}
else return (*lptr++);
}
}
struct table {
char *name;
int type, value;
};
static struct table mdtab[] = {
{"january", MONTH, 1},
{"february", MONTH, 2},
{"march", MONTH, 3},
{"april", MONTH, 4},
{"may", MONTH, 5},
{"june", MONTH, 6},
{"july", MONTH, 7},
{"august", MONTH, 8},
{"september", MONTH, 9},
{"sept", MONTH, 9},
{"october", MONTH, 10},
{"november", MONTH, 11},
{"december", MONTH, 12},
{"sunday", DAY, 0},
{"monday", DAY, 1